import nltk,sys,os
from nltk.corpus import cmudict
# 分句
from nltk.tokenize import sent_tokenize
# 自定义的停止词
from myconstantnlp import stopwordDict
from datetime import datetime


# nltk中的cmudict模块所提供的发音为美音。它是基于卡内基梅隆大学的发音词典，而该词典主要收录的是美式英语的发音。

# 下载 cmudict 语料库
# nltk.download('cmudict')

# 部分cmudict音标到国际音标（涵盖英音、美音通用部分）的对应关系
cmu_to_ipa = {'AA':'ɑ','AE':'æ','AH':'ʌ','AO':'ɔ','AW':'aʊ','AY':'aɪ','EH':'ɛ','ER':'ɝ','EY':'eɪ','IH':'ɪ','IY':'i','OW':'oʊ',
           'OY':'ɔɪ','UH':'ʊ','UW':'u','B':'b','CH':'tʃ','D':'d','DH':'ð','F':'f','G':'ɡ','HH':'h','JH':'dʒ','K':'k','L':'l',
           'M':'m','N':'n','NG':'ŋ','P':'p','R':'r','S':'s','SH':'ʃ','T':'t','TH':'θ','V':'v','W':'w','Y':'j','Z':'z','ZH':'ʒ'}
# 带数字的音标 字母后面跟数字的形式表示音节的重音，数字`0`表示非重读音节，`1`表示主重读音节，`2`表示次重读音节
cmu_num_to_ipa = {'AA0':'ɑː','AA1':'ɑː','AE0':'æ','AE1':'æ','AH0':'ə','AH1':'ʌ','AO0':'ɔː','AO1':'ɔː','AW0':'aʊ','AW1':'aʊ',
                'AY0':'aɪ','AY1':'aɪ','AY2':'aɪ','EH0':'e','EH1':'e','EH2':'e','ER0':'ɚ','ER1':'ɝ','EY0':'eɪ','EY1':'eɪ',
                'IH0':'ɪ','IH1':'ɪ','IH2':'ɪ','IY0':'i','IY1':'i','OW0':'oʊ','OW1':'oʊ','OY0':'ɔɪ','OY1':'ɔɪ','UH0':'ʊ','UH1':'ʊ','UW0':'u','UW1':'u'}
# 两个字典合并
cmudict_ipa = {**cmu_to_ipa,**cmu_num_to_ipa}
# 加载发音词典
d = cmudict.dict()
# 加载发音元组
t = cmudict.entries()

# 大字典
def getWordPhoneticFromDict(word:str):
    if not d.get(word.lower()):
        return []
    d_phonetic = d[word.lower()]
    length = len(d_phonetic)
    if length == 1:
        return d_phonetic[0]
    elif length > 0:
        print(f'{word}:{d_phonetic}')
        return d_phonetic[0]
# 大元组
def getWordPhoneticFromTuple(word:str):
    for e in t:
        if word.lower() == e[0]:
            # print(f'{word}:{e}')
            return e[1]
    return []
# 处理重音、次重音
stress_mark = {'0':'','1':'ˈ','2':'ˌ'}
def processPhoneticForStressAccent(phonetics:list):
    sum = len(phonetics)
    out = []
    for index in range(sum):
        current_ph = phonetics[index]
        if index>0 and current_ph[-1].isdigit(): # XX1|XX2|XX0
            pre_ph = out[index-1]
            out[index-1] = f'{stress_mark[str(current_ph[-1])]}{pre_ph}'
        out.append(cmudict_ipa[current_ph])
    return ''.join(out).replace('tˈr','ˈtr')


# ---- test begin ----- #
def lookup_word(word_s):
    return cmudict.dict().get(word_s)        # standard dict access

def lookup2_word(word_s):
    entries = [e[1] for e in cmudict.entries() if e[0] == word_s]
    return entries

def count_syllables(word_s):
    count = 0
    phones = lookup_word(word_s)
    if phones:
        phones0 = phones[0]
        count = len([p for p in phones0 if p[-1].isdigit()])
    return count

# test_word = 'hello'
# phones = lookup_word(test_word)
# phones2 = lookup2_word(test_word)
# count = count_syllables(test_word)
# print(f"PHONES({test_word!r}) yields {phones}\nCOUNT is {count}")
# print(f"PHONES are same: {phones == phones2}")
# ---- teset end ----- #
'''分词'''
def getwordlist(sentence:str):
    return nltk.pos_tag(nltk.word_tokenize(sentence))
'''分句'''
def getsentencelist(context):
    return sent_tokenize(context)
def processSentence(sentence:str):
    tokens = getwordlist(sentence)
    out_sentence = sentence
    for token,pos in tokens:
        if stopwordDict.__contains__(token.lower()):
            continue
        phonetic = processPhoneticForStressAccent(getWordPhoneticFromDict(token))
        # print(token,pos,phonetic)
        out_sentence = out_sentence.replace(token,f'{token}[{phonetic}]')
    return out_sentence

outputFile = './'

def mainProcess():
    timestamp = datetime.now()
    formatted_dt = timestamp.strftime('%Y%m%d%H%M%S')
    with open('./content.txt','r',encoding='utf-8') as f:
        content = f.read()
    sentences = getsentencelist(content)
    out_content = f'# {formatted_dt}\n'
    no = 1
    for sentence in sentences:
        out = processSentence(sentence)
        # print(out)
        out_content += f'\n{str(no)}. {sentence}\n    > {out}\n'
        no += 1
    with open(os.path.join(outputFile,f'en_phonetic_{formatted_dt}.md'),'w',encoding='utf-8') as ofile:
        ofile.write(out_content)

if __name__ =='__main__':
    if len(sys.argv) == 2:
        outputFile = sys.argv[1]
    mainProcess()
